#ifndef ALIAOD3LH_H
#define ALIAOD3LH_H
/* Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
 * See cxx source for full Copyright notice                               */

//-------------------------------------------------------------------------
//     Analysis Oriented Data (AOD) 3LH vertex class
//     Authors: B.Hippolyte, IPHC, hippolyt@in2p3.fr 
//              G.Van Buren, BNL,  gene@bnl.gov      (original STAR MuDsts)
//-------------------------------------------------------------------------
class AliAODRecoDecay;
class AliAODVertex;
class AliESDv0;

#include "AliAODRecoDecay.h"
#include "AliAODVertex.h"

class AliAOD3LH : public AliAODRecoDecay {

public:

  AliAOD3LH();

  AliAOD3LH(const AliESDv0& rv0vertex, AliAODVertex *fAODvertex,Double_t d0[2]);

  AliAOD3LH(AliAODVertex *rAODVertex, Double_t rDca3LHDaughters, Double_t rDca3LHToPrimVertex,
	   const Double_t *rMomPos, const Double_t *rMomNeg, Double_t *rDcaDaughterToPrimVertex);
  virtual ~AliAOD3LH();

  AliAOD3LH(const AliAOD3LH& rAliAOD3LH);
  AliAOD3LH& operator=(const AliAOD3LH& rAliAOD3LH);

  void     Fill(AliAODVertex *rAODVertex, Double_t rDca3LHDaughters, Double_t rDca3LHToPrimVertex,
		const Double_t *rMomPos, const Double_t *rMomNeg, const Double_t *rDcaDaughterToPrimVertex);
  void     Reset3LH();
  void     Print(Option_t* option = "") const;

  void     SetOnFlyStatus(Bool_t status){fOnFlyStatus=status;}
  Bool_t   GetOnFlyStatus() const {return fOnFlyStatus;}

  Double_t DecayVertex3LHX() const;
  Double_t DecayVertex3LHY() const;
  Double_t DecayVertex3LHZ() const;

  Double_t DecayLength3LH(const Double_t *) const;
                     
  Double_t Dca3LHDaughters()     const;
  Double_t Dca3LHToPrimVertex()  const;
  Double_t DcaPosToPrimVertex() const; 
  Double_t DcaNegToPrimVertex() const; 
  Double_t Radius3LH()           const;
  Double_t OpenAngle3LH()        const;

  Double_t MomPosX() const;
  Double_t MomPosY() const;
  Double_t MomPosZ() const;
  Double_t MomNegX() const;
  Double_t MomNegY() const;
  Double_t MomNegZ() const;

  Double_t Chi23LH()  const;

  Double_t Mom3LHX()  const;
  Double_t Mom3LHY()  const;
  Double_t Mom3LHZ()  const;

  Double_t Ptot2Pos() const;
  Double_t Ptot2Neg() const;
  Double_t Ptot23LH()  const;
  Double_t Pt23LH()    const;
  Double_t MomPosAlong3LH() const;
  Double_t MomNegAlong3LH() const;
  Double_t Alpha3LH() const;
  Double_t PtArm3LH() const;
  Double_t EPosProton() const;
  Double_t ENegProton() const;
  Double_t EPosPion() const;
  Double_t ENegPion() const;
  Double_t ELambda() const;
  Double_t EK0Short() const;
  Double_t MassLambda() const;
  Double_t MassAntiLambda() const;
  Double_t MassK0Short() const;
  Double_t RapK0Short() const;
  Double_t RapLambda() const;
  Double_t PseudoRap3LH()    const;
  Double_t PseudoRapPos()   const;
  Double_t PseudoRapNeg()   const;
  
  Short_t  GetPosID()       const;
  Short_t  GetNegID()       const;
  Int_t    GetLabel()       const {return -1;} // Dummy
  Int_t    PdgCode()        const {return  0;} // Dummy
  
  virtual Bool_t   GetPxPyPz(Double_t */*p*/) const { return kFALSE; }
  virtual void     SetID(Short_t /*id*/) {;}

  
protected:
  Double32_t fDca3LHToPrimVertex;    // dca of 3LH to primary vertex 
  Bool_t     fOnFlyStatus;          // if kTRUE, then this 3LH is recontructed
                                    // "on fly" during the tracking
  ClassDef(AliAOD3LH,2)
};

inline Double_t AliAOD3LH::DecayVertex3LHX() const {return this->GetSecVtxX();}
inline Double_t AliAOD3LH::DecayVertex3LHY() const {return this->GetSecVtxY();}
inline Double_t AliAOD3LH::DecayVertex3LHZ() const {return this->GetSecVtxZ();}

inline Double_t AliAOD3LH::DecayLength3LH(const Double_t *tParentVertexPosition) const {
  return ::sqrt(::pow(DecayVertex3LHX() - tParentVertexPosition[0],2) +
		::pow(DecayVertex3LHY() - tParentVertexPosition[1],2) +
		::pow(DecayVertex3LHZ() - tParentVertexPosition[2],2));
}

inline Double_t AliAOD3LH::Dca3LHDaughters() const {return fDCA[0];}
inline Double_t AliAOD3LH::Dca3LHToPrimVertex() const {return fDca3LHToPrimVertex;}
inline Double_t AliAOD3LH::DcaPosToPrimVertex() const {return fd0[0];}
inline Double_t AliAOD3LH::DcaNegToPrimVertex() const {return fd0[1];}

inline Double_t AliAOD3LH::Radius3LH() const {
  return RadiusSecVtx();
}

inline Double_t AliAOD3LH::OpenAngle3LH() const {
  Double_t lScalPtot1Ptot2 = PxProng(0)*PxProng(1)+PyProng(0)*PyProng(1)+PzProng(0)*PzProng(1);
  Double_t lPtot1xPtot2 = Ptot2Pos()*Ptot2Neg();
  return ::acos(lScalPtot1Ptot2/::sqrt(lPtot1xPtot2) );
}

inline Double_t AliAOD3LH::MomPosX() const {return fPx[0];}
inline Double_t AliAOD3LH::MomPosY() const {return fPy[0];}
inline Double_t AliAOD3LH::MomPosZ() const {return fPz[0];}
inline Double_t AliAOD3LH::MomNegX() const {return fPx[1];}
inline Double_t AliAOD3LH::MomNegY() const {return fPy[1];}
inline Double_t AliAOD3LH::MomNegZ() const {return fPz[1];}

inline Double_t AliAOD3LH::Chi23LH() const {return GetSecondaryVtx()->GetChi2perNDF();}

// Compare eventually AliAOD3LH::Mom3LHX() and AliAODRecoDecay::Px()
inline Double_t AliAOD3LH::Mom3LHX() const {return MomPosX()+MomNegX();}
inline Double_t AliAOD3LH::Mom3LHY() const {return MomPosY()+MomNegY();}
inline Double_t AliAOD3LH::Mom3LHZ() const {return MomPosZ()+MomNegZ();}

inline Double_t AliAOD3LH::Ptot2Pos() const {
  return (::pow(MomPosX(),2) + ::pow(MomPosY(),2) + ::pow(MomPosZ(),2) );
}
inline Double_t AliAOD3LH::Ptot2Neg() const {
  return (::pow(MomNegX(),2) + ::pow(MomNegY(),2) + ::pow(MomNegZ(),2) );
}
inline Double_t AliAOD3LH::Ptot23LH() const {return ( Pt23LH() + ::pow(Mom3LHZ(),2) );}
inline Double_t AliAOD3LH::Pt23LH() const {
  return (::pow(Mom3LHX(),2) + ::pow(Mom3LHY(),2) );
}

inline Double_t AliAOD3LH::MomPosAlong3LH() const {
  Double_t lPtot23LH = Ptot23LH();
  if (lPtot23LH)
    return (MomPosX()*Mom3LHX() +
	    MomPosY()*Mom3LHY() +
	    MomPosZ()*Mom3LHZ()) / ::sqrt(lPtot23LH);
  return 0.;
}

inline Double_t AliAOD3LH::MomNegAlong3LH() const {
  Double_t lPtot23LH = Ptot23LH();
  if (lPtot23LH)
    return (MomNegX()*Mom3LHX() +
	    MomNegY()*Mom3LHY() +
	    MomNegZ()*Mom3LHZ()) / ::sqrt(lPtot23LH);
  return 0.;
}

inline Double_t AliAOD3LH::Alpha3LH() const {
  return Alpha();
}
inline Double_t AliAOD3LH::PtArm3LH() const {
  return QtProng(0);
}

inline Double_t AliAOD3LH::EPosProton() const {
  return EProng(0,2212);
}

inline Double_t AliAOD3LH::ENegProton() const {
  return EProng(1,2212);
}

inline Double_t AliAOD3LH::EPosPion() const {
  return EProng(0,211);
}

inline Double_t AliAOD3LH::ENegPion() const {
  return EProng(1,211);
}

inline Double_t AliAOD3LH::ELambda() const {
  return E(3122);
}

inline Double_t AliAOD3LH::EK0Short() const {
  return E(310);
}

inline Double_t AliAOD3LH::MassLambda() const {
  return InvMass2Prongs(0,1,2212,211);
}

inline Double_t AliAOD3LH::MassAntiLambda() const {
  return InvMass2Prongs(0,1,211,2212);
}

inline Double_t AliAOD3LH::MassK0Short() const {
  return InvMass2Prongs(0,1,211,211);
}

inline Double_t AliAOD3LH::RapK0Short() const {
  return Y(310);
}

inline Double_t AliAOD3LH::RapLambda() const {
  return Y(3122);
}

inline Double_t AliAOD3LH::PseudoRap3LH() const {
  return Eta();
}

inline Double_t AliAOD3LH::PseudoRapPos()   const {
  return EtaProng(0);
}

inline Double_t AliAOD3LH::PseudoRapNeg()   const {
  return EtaProng(1);
}
//----------------------------------------------------------------------------

#endif
